package cn.cycleif.app.service;

import cn.cycleif.app.domain.dto.UserLoginDTO;
import cn.cycleif.app.domain.vo.VerifyCodeVO;
import cn.cycleif.app.mapper.UserMapper;
import cn.cycleif.component.redis.RedisCache;
import cn.cycleif.entity.User;
import cn.cycleif.enums.ResultCodeEnum;
import cn.cycleif.enums.UserStatusEnum;
import cn.cycleif.util.EncryptUtil;
import cn.cycleif.util.R;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Objects;
import java.util.UUID;

import static cn.cycleif.constants.RedisConstant.CAPTCHA_CODE;

/**
 * @Date: 25/1/22-22:40
 * @Desc:
 */
@Service
public class LoginService extends ServiceImpl<UserMapper, User> {

  @Autowired
  private UserService userService;
  @Autowired
  private RedisCache  redisCache;

  public R<VerifyCodeVO> getCaptcha() {
    String captchaKey = UUID.randomUUID()
                            .toString();
    // 定义图形验证码的长、宽、验证码字符数、干扰线宽度
    ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(140, 40, 4, 0);
    // 存入redis并设置过期时间为1分钟
    redisCache.set(CAPTCHA_CODE + captchaKey, shearCaptcha.getCode(), 60L);
    String base64String = "";
    try {
      base64String = "data:image/png;base64," + shearCaptcha.getImageBase64();
    } catch (Exception e) {
      e.printStackTrace();
    }
    VerifyCodeVO codeVO = VerifyCodeVO.builder()
                                      .captchaKey(captchaKey)
                                      .captchaBase64(base64String)
                                      .build();
    return R.success(codeVO);
  }

  public R<String> login(UserLoginDTO dto) {
    //  验证码校验
    // String captchaKey = dto.getCaptchaKey();
    // if (captchaKey == null || dto.getCaptchaCode() == null) {
    //   throw new BaseException("验证码不能为空");
    // }
    // if (redisCache.getExpire(CAPTCHA_CODE + captchaKey) == -2) {
    //   throw new BaseException("验证码已过期");
    // }
    // if (!redisCache.get(CAPTCHA_CODE + captchaKey).equals(dto.getCaptchaCode())) {
    //   throw new BaseException("验证码错误");
    // }
    User user = null;
    if (dto.getUsername() != null) {
      user = userService.getOne(
          new LambdaQueryWrapper<User>().eq(User::getUsername, dto.getUsername())
      );
    } else if (dto.getEmail() != null) {
      user = userService.getOne(
          new LambdaQueryWrapper<User>().eq(User::getMail, dto.getEmail())
      );
    }
    if (Objects.isNull(user)) return R.error(ResultCodeEnum.ERROR_USER_NOT_EXIST);
    if (!EncryptUtil.validate(user.getPassword(), dto.getPassword()))
      return R.error(ResultCodeEnum.ERROR_PASSWORD_WRONG);
    // 是否已禁用或其他
    UserStatusEnum status = user.getStatus();
    if (status != UserStatusEnum.ACTIVE)
      return R.error((ResultCodeEnum.ERROR_DISABLE_ACCOUNT));

    //  登录，记住或不记住
    if (Boolean.TRUE.equals(dto.getRememberMe())) {
      StpUtil.login(user.getId(), new SaLoginModel().setTimeout(60 * 60 * 24 * 7L));
    } else {
      StpUtil.login(user.getId(), "system");
    }
    // 更新登录时间
    user.setLastLoginAt(LocalDateTime.now());
    userService.updateById(user);

    //  3、返回token
    return R.success(StpUtil.getTokenValue());
  }

  public R<String> checkLogin() {
    StpUtil.checkLogin();
    return R.success();
  }
}
